package com.youlu.campus.service.invite.impl;

import com.alibaba.fastjson.JSONObject;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.entity.ActivityTaskInfo;
import com.youlu.campus.entity.UserInviteRecord;
import com.youlu.campus.entity.enums.TaskBizType;
import com.youlu.campus.service.activity.ActivityTaskService;
import com.youlu.campus.service.invite.UserInviteRecordService;
import com.youlu.campus.service.ranking.UserInviteCountRankingService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class UserInviteRecordServiceImpl implements UserInviteRecordService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private ActivityTaskService activityTaskService;
    @Autowired
    private UserInviteCountRankingService userInviteCountRankingService;

    @Resource(name = "masterMongoTemplate")
    private MongoTemplate masterMongoTemplate;

    @Override
    public List<UserInviteRecord> findByInvitedToUserId(String invitedToUserId, String activityId, String taskId) {
        log.info(":>>> 开始查询用户被邀请记录:{},{},{}", invitedToUserId, activityId, taskId);
        if (StringUtils.isBlank(invitedToUserId) || StringUtils.isBlank(activityId) || StringUtils.isBlank(taskId)) {
            log.error(":>>> 获取用户被邀请记录参数错误");
            return new ArrayList<>();
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("invitedToUserId").is(invitedToUserId).and("activityId").is(activityId).and(
                "taskId").is(taskId));
        List<UserInviteRecord> records = mongoTemplate.find(query, UserInviteRecord.class);
        if (Objects.isNull(records)) {
            return new ArrayList<>();
        }
        return records;
    }

    @Override
    public UserInviteRecord findByInvitedToUserId(String invitedToUserId, String activityId) {
        log.info(":>>> 开始查询用户被邀请记录:{},{},{}", invitedToUserId, activityId);
        if (StringUtils.isBlank(invitedToUserId) || StringUtils.isBlank(activityId)) {
            log.error(":>>> 获取用户被邀请记录参数错误");
            return null;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("invitedToUserId").is(invitedToUserId).and("activityId").is(activityId).and("joinStatus").is(Boolean.TRUE));
        return masterMongoTemplate.findOne(query, UserInviteRecord.class);
    }

    @Override
    public UserInviteRecord getByInvitedToUserId(String invitedToUserId, String activityId, String taskId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("invitedToUserId").is(invitedToUserId).and("activityId").is(activityId).and(
                "taskId").is(taskId));
        return this.masterMongoTemplate.findOne(query, UserInviteRecord.class);
    }

    @Override
    public List<UserInviteRecord> find(String invitedByUserId, String activityId, String taskId) {
        log.info(":>>> 开始查询用户邀请记录:{},{},{}", invitedByUserId, activityId, taskId);
        if (StringUtils.isBlank(invitedByUserId) || StringUtils.isBlank(activityId) || StringUtils.isBlank(taskId)) {
            log.error(":>>> 获取用户邀请记录参数错误");
            return new ArrayList<>();
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("invitedByUserId").is(invitedByUserId).and("activityId").is(activityId).and(
                "taskId").is(taskId).and("joinStatus").is(Boolean.TRUE));
        List<UserInviteRecord> records = mongoTemplate.find(query, UserInviteRecord.class);
        if (Objects.isNull(records)) {
            return new ArrayList<>();
        }
        return records;
    }

    @Override
    public Long getInviteUserCount(String userId, String activityId, String taskId, Boolean joinStatus) {
        log.info(":>>> 开始查询用户的邀请数量:userId:{},activityId:{},taskId:{},joinStatus:{}", userId, activityId, taskId,
                joinStatus);
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(activityId) || StringUtils.isBlank(taskId)) {
            log.error(":>>> 获取用户邀请数量错误:参数错误");
            return 0L;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("invitedByUserId").is(userId).and("activityId").is(activityId).and("taskId").is(taskId));
        if (Objects.nonNull(joinStatus)) {
            query.addCriteria(Criteria.where("joinStatus").is(joinStatus));
        }
        Long count = mongoTemplate.count(query, UserInviteRecord.class);
        log.info(":>>> 用户:{},邀请人数为:{}", userId, count);
        return count;
    }

    @Override
    public boolean updateUserInviteStatus(String invitedByUserId, String invitedToUserId, String activityId,
                                          String taskId, Boolean joinStatus) {
        log.info(":>>> 开始更新活动:{},任务:{},邀请人:{},收邀人:{},状态:{}", activityId, taskId, invitedByUserId, invitedToUserId,
                joinStatus);
        if (StringUtils.isBlank(invitedByUserId) || StringUtils.isBlank(invitedToUserId) || StringUtils.isBlank(activityId) || Objects.isNull(joinStatus)) {
            log.error(":>>> 更新用户邀请状态错误:参数错误");
            return false;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("invitedByUserId").is(invitedByUserId).and("invitedToUserId").is(invitedToUserId).and("activityId").is(activityId));
        if (StringUtils.isNotBlank(taskId)) {
            query.addCriteria(Criteria.where("taskId").is(taskId));
        }
        Date date = new Date();
        Update update = new Update();
        update.set("joinTime", date);
        update.set("updatedTime", date);
        update.set("joinStatus", joinStatus);
        UpdateResult result = mongoTemplate.updateMulti(query, update, UserInviteRecord.class);
        log.info(":>>> 结束更新活动:{},任务:{},邀请人:{},收邀人:{},状态:{} --->>> 结果为:{}", activityId, taskId, invitedByUserId,
                invitedToUserId, joinStatus, result.getModifiedCount());
        return result.getModifiedCount() > 0 ? true : false;
    }

    @Override
    public boolean updateUserInviteStatus(String id) {
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        Date now = new Date();
        Update update = new Update();
        update.set("joinStatus", true);
        update.set("joinTime", now);
        update.set("updatedTime", now);
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, UserInviteRecord.class);
        return updateResult.getModifiedCount() > 0 ? true : false;
    }

    @Override
    public void updateInvitedStatus(String invitedToUserId, String activityId) {
        log.info(":>>> 开始更新被邀请人报名状态,invitedToUserId:{},activityId:{}", invitedToUserId, activityId);
        ActivityTaskInfo taskInfo = activityTaskService.find(activityId, TaskBizType.INVITE);
        if (Objects.isNull(taskInfo)) {
            log.error(":>>> 活动邀请任务不存在，请配置!activityId:{}", activityId);
            return;
        }
        UserInviteRecord record = this.getByInvitedToUserId(invitedToUserId, activityId, taskInfo.getId());
        if (Objects.isNull(record)) {
            log.error(":>>> 被邀请记录不存在，activityId:{},invitedToUserId:{},taskId:{}", activityId,
                    invitedToUserId, taskInfo.getId());
            return;
        }
        this.updateUserInviteStatus(record.getId());
        if (StringUtils.isNotBlank(record.getInvitedByUserId())) {
            userInviteCountRankingService.updateCount(record.getInvitedByUserId(), activityId, record.getAppId(), record.getPlatform(), 1);
        }

    }

    @Override
    public boolean updateInvitedCount(String invitedToUserId, String activityId) {
        log.info(":>>> 开始更新被邀请人报名状态,invitedToUserId:{},activityId:{}", invitedToUserId, activityId);
        ActivityTaskInfo taskInfo = activityTaskService.find(activityId, TaskBizType.INVITE);
        if (Objects.isNull(taskInfo)) {
            log.error(":>>> 活动邀请任务不存在，请配置!activityId:{}", activityId);
            return false;
        }
        UserInviteRecord record = this.getByInvitedToUserId(invitedToUserId, activityId, taskInfo.getId());
        if (Objects.isNull(record)) {
            log.error(":>>> 被邀请记录不存在，activityId:{},invitedToUserId:{},taskId:{}", activityId,
                    invitedToUserId, taskInfo.getId());
            return false;
        }
        if (record.getJoinStatus()) {
            log.info(":>>> 已经邀请了，activityId:{},invitedToUserId:{},taskId:{}", activityId,
                    invitedToUserId, taskInfo.getId());
            return false;
        }
        this.updateUserInviteStatus(record.getId());
        if (StringUtils.isNotBlank(record.getInvitedByUserId())) {
            return userInviteCountRankingService.updateInviteCount(record.getInvitedByUserId(), activityId,
                    record.getAppId(), record.getPlatform(), 1);
        }
        return false;
    }

    @Override
    public UserInviteRecord invitedSuccessByInvitedToUserIdAndActivityId(String invitedToUserId, String activityId, String taskId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("invitedToUserId").is(invitedToUserId).and("activityId").is(activityId).and("taskId").is(taskId).and("joinStatus").is(Boolean.TRUE));
        return this.masterMongoTemplate.findOne(query, UserInviteRecord.class);
    }

    @Override
    public UserInviteRecord invitedSuccessByInvitedToUserIdAndActivityId(String invitedToUserId, String activityId) {
        if (StringUtils.isBlank(invitedToUserId) || StringUtils.isBlank(activityId)) {
            log.error(":>>> 获取用户被邀请记录参数错误");
            return null;
        }
        ActivityTaskInfo activityTaskInfo = activityTaskService.find(activityId, TaskBizType.INVITE);
        if (Objects.isNull(activityTaskInfo)) {
            log.error(":>>> 获取用户被邀请记录参数错误，未查询到邀请任务");
            return null;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("invitedToUserId").is(invitedToUserId).and("activityId").is(activityId).and("taskId").is(activityTaskInfo.getId()).and("joinStatus").is(Boolean.TRUE));
        return this.masterMongoTemplate.findOne(query, UserInviteRecord.class);
    }

    @Override
    public void deleteByInvitedByUserIdAndActivityId(String userId, String activityId) {
        log.info("deleteByInvitedByUserIdAndActivityId userId:{},activityId:{}", userId, activityId);
        Query query = Query.query(Criteria.where("invitedByUserId").is(userId)
                .and("activityId").is(activityId));
        DeleteResult deleteResult = mongoTemplate.remove(query, UserInviteRecord.class);
        log.info("deleteByInvitedByUserIdAndActivityId deleteResult:{}", JSONObject.toJSONString(deleteResult));
    }
}
